NoPaste Service
DOWNLOAD
Language: C
Author: Matrix86
Description: [Raw Socket] Inviare un SYN packet
Date: 22/03/09 15:30
  1. #include <sys/socket.h>
  2. #include <netinet/ip.h>
  3. #include <netinet/tcp.h>
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>
  6. #include <errno.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10.  
  11. #define LENPKT                  8192            // lunghezza del pacchetto
  12.  
  13. // Destinazione
  14. #define DESTINATION             "192.168.0.102" // IP del destinatario
  15. #define PORTD                   80                      // Porta destinazione
  16.  
  17. // Sorgente
  18. #define SOURCE                  "192.168.0.101" // IP sorgente
  19. #define PORTS                   5678            // Porta sorgente
  20.  
  21. // Struttura che useremo per il calcolo del checksum TCP
  22. struct checkpkt_header
  23. {
  24.         unsigned long saddr;
  25.         unsigned long daddr;
  26.         char dummy;
  27.         unsigned char protocol;
  28.         unsigned short len;
  29.         struct tcphdr tcp;
  30. };
  31.  
  32. // Funzione per il calcolo del checksum dell'header IP
  33. unsigned short ip_checksum( unsigned short * b, int len ) {
  34.         unsigned long sum = 0;  // long = 32bit
  35.        
  36.         // Sommo il pacchetto IP a 16bit alla volta e se il bit pił significativo e settato (1) lo sommo ai primi 16bit
  37.         while( len > 0 ) {
  38.                 sum += *b++; // Unsigned short = 2 bytes (16bit)
  39.                 len--;
  40.         }
  41.        
  42.         while(sum >> 16)
  43.                 sum = (sum & 0xFFFF) + (sum >> 16);
  44.  
  45.         return ~sum;
  46. }
  47.  
  48. // Funzione per il calcolo del checksum dell'header TCP
  49. unsigned short tcp_checksum( unsigned short * buf, int len ) {
  50.  
  51.     int nleft = len;
  52.     unsigned short *w = buf;
  53.         int sum = 0;
  54.     unsigned short answer = 0;
  55.  
  56.     while( nleft > 1 ) {
  57.                 sum += *w++;
  58.                 nleft -= 2;
  59.     }
  60.  
  61.     if( nleft == 1 ) {
  62.                 *(unsigned char *) (&answer) = *(u_char *) w;
  63.                 sum += answer;
  64.     }
  65.  
  66.     sum = (sum >> 16) + (sum & 0xffff);
  67.     sum += (sum >> 16);
  68.     answer = ~sum;
  69.  
  70.     return (answer);
  71. }
  72.  
  73. // Funzione per l'invio del pacchetto con il flag SYN settato
  74. int sendpkt( int socket, char *destip, char *sourceip, int dport, int sport ) {
  75.         char buffer[LENPKT];
  76.         // IP Header
  77.         struct iphdr *iph = (struct iphdr *) buffer;
  78.         // TCP Header ( packet = IP Header + TCP Header )
  79.         struct tcphdr *tcph = (struct tcphdr *) ( iph + 1 );
  80.         struct sockaddr_in sin;
  81.         struct checkpkt_header *checkpkt;
  82.        
  83.         bzero( buffer, LENPKT );
  84.        
  85.         sin.sin_family = AF_INET;
  86.         sin.sin_port = htons( dport );                                  // Port Destination
  87.         sin.sin_addr.s_addr = inet_addr( destip );              // IP Destination
  88.        
  89.         // Riempiamo l'header del pacchetto IP
  90.         iph->ihl = 5;
  91.         iph->version = 4;
  92.         iph->tos = 16;
  93.         iph->tot_len = sizeof( struct iphdr ) + sizeof( struct tcphdr );
  94.         iph->id = htons(52407);
  95.         iph->frag_off = 0;
  96.         iph->ttl = 64;
  97.         iph->protocol = 6;
  98.         iph->check = 0;
  99.         iph->saddr = inet_addr( sourceip );
  100.         iph->daddr = inet_addr( destip );
  101.        
  102.         // Riempiamo l'header del pacchetto TCP
  103.         tcph->source = htons( sport );
  104.         tcph->dest = htons( dport );
  105.         tcph->seq = htonl(1);
  106.         tcph->ack_seq = 0;
  107.         tcph->doff = 5;
  108.         tcph->syn = 1;          // Flag SYN
  109.         tcph->ack = 0;
  110.         tcph->window = htons(32767);
  111.         tcph->check = 0;  // In teoria impostando a 0 il checksum del tcp (tcp checksum offload) se ne preoccupa la scheda di rete
  112.         tcph->urg_ptr = 0;
  113.        
  114.         // Inseriamo il checksum nell'header IP ora che abbiamo riempito tutto
  115.         iph->check = ip_checksum( (unsigned short *) buffer, sizeof( struct iphdr ) + sizeof( struct tcphdr ) );
  116.        
  117.         // Calcoliamo il checksum tcp manualmente...
  118.         checkpkt = (struct checkpkt_header *) malloc( sizeof( struct checkpkt_header ) );
  119.         memset( checkpkt, 0, sizeof( struct checkpkt_header ) );
  120.         checkpkt->saddr     = iph->saddr;
  121.         checkpkt->daddr     = iph->daddr;
  122.         checkpkt->protocol  = IPPROTO_TCP;       
  123.         checkpkt->len           = htons( sizeof(struct tcphdr) );
  124.         checkpkt->tcp       = *tcph;
  125.        
  126.         tcph->check = tcp_checksum( (unsigned short *) checkpkt, sizeof( struct checkpkt_header ) );
  127.        
  128.         // Invio del pacchetto!
  129.         if( sendto( socket, buffer, iph->tot_len, 0, (struct sockaddr *) &sin, sizeof(sin) ) < 0 )
  130.                 return 1;
  131.        
  132.         return 0;
  133. }
  134.  
  135. void setsocket( int sd ) {
  136.         int yes;
  137.        
  138.         // Diciamo al kernel che abbiamo gią preparato noi l'header IP del pacchetto
  139.         if( setsockopt( sd, IPPROTO_IP, IP_HDRINCL, &yes, sizeof(yes) ) < 0 ) {
  140.                 fprintf( stderr, "[ERROR] %s", strerror( errno ) );
  141.                 exit(0);
  142.         }
  143.        
  144.         return;
  145. }
  146.  
  147. int main(){
  148.         int sock;
  149.        
  150.         if( geteuid() ){
  151.         fprintf( stderr, "[ERROR] Bisogna avere i permessi di root per eseguire l'applicazione\n" );
  152.                 exit(0);
  153.         }
  154.        
  155.         sock = socket( PF_INET, SOCK_RAW, IPPROTO_TCP );
  156.         if( sock < 0 ) {
  157.                 fprintf( stderr, "[ERROR] %s", strerror( errno ) );
  158.                 exit(0);
  159.         }
  160.        
  161.         setsocket( sock );
  162.        
  163.         if( !sendpkt( sock, DESTINATION, SOURCE, PORTD, PORTS ) )
  164.                 printf( "Pacchetto inviato!\n\n" );
  165.         else
  166.                 printf( "Pacchetto non inviato!\n\n" );
  167.        
  168.         printf( "Exit.\n" );
  169.  
  170.         return 0;
  171. }
  172.